package seismosurfer.gui.panel;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import seismosurfer.data.QuakeMaxMinData;
import seismosurfer.gui.GUIConstants;
import seismosurfer.gui.TimeSlider;
import seismosurfer.util.TimeUtil;

import com.bbn.openmap.gui.OMComponentPanel;

/**
 * This panel is used to configure the data that
 * will be displayed through the time slider.
 *
 */
public class ConfigureSliderPanel extends OMComponentPanel implements
        Serializable, GUIConstants {
    
    private static final long serialVersionUID = 7568737734909635977L;

    protected JComboBox timeResCombo;

    protected SpinnerNumberModel magminSM;

    protected SpinnerNumberModel magmaxSM;

    protected SpinnerNumberModel yearminSM;

    protected SpinnerNumberModel yearmaxSM;

    protected SpinnerNumberModel monthminSM;

    protected SpinnerNumberModel monthmaxSM;

    protected SpinnerNumberModel dayminSM;

    protected SpinnerNumberModel daymaxSM;

    public final static String pack = "pack";

    // These values are entered at the Configure Slider Dialog.
    double magMin, magMax;

    int yearMin, yearMax;

    int monthMin, monthMax;

    int dayMin, dayMax;

    public ConfigureSliderPanel(ActionListener buttonsListener) {
        super();
        createPanel(buttonsListener);
    }

    public double getMagMin() {
        return magMin;
    }

    public double getMagMax() {
        return magMax;
    }

    public int getYearMin() {
        return yearMin;
    }

    public int getYearMax() {
        return yearMax;
    }

    public int getMonthMin() {
        return monthMin;
    }

    public int getMonthMax() {
        return monthMax;
    }

    public int getDayMin() {
        return dayMin;
    }

    public int getDayMax() {
        return dayMax;
    }

    public String getTimeResolution() {
        return (String) timeResCombo.getSelectedItem();
    }

    protected void createPanel(ActionListener buttonsListener) {

        GridBagLayout contentPaneLayout = new GridBagLayout();
        GridBagConstraints ccP = new GridBagConstraints();
        setLayout(contentPaneLayout);

        JPanel magPanel = new JPanel();
        magPanel.setBorder(BorderFactory.createTitledBorder("Magnitude"));
        GridBagLayout magPanelLayout = new GridBagLayout();
        GridBagConstraints magPanelCon = new GridBagConstraints();
        magPanel.setLayout(magPanelLayout);
        JLabel minMagLabel = new JLabel("Min");
        magPanelCon.gridx = 0;
        magPanelCon.gridy = 0;
        magPanelLayout.setConstraints(minMagLabel, magPanelCon);
        magPanel.add(minMagLabel);
        JLabel maxMagLabel = new JLabel("Max");
        magPanelCon.gridx = 1;
        magPanelCon.gridy = 0;
        magPanelLayout.setConstraints(maxMagLabel, magPanelCon);
        magPanel.add(maxMagLabel);
        double magmin = 0;
        double magmax = 0;

        magmin = QuakeMaxMinData.getDBMinMagnitude();
        magmax = QuakeMaxMinData.getDBMaxMagnitude();

        magminSM = new SpinnerNumberModel(magmin + 0.1, magmin, magmax, 0.1);
        JSpinner magminSp = new JSpinner(magminSM);
        magPanelCon.gridx = 0;
        magPanelCon.gridy = 1;
        magPanelLayout.setConstraints(magminSp, magPanelCon);
        magPanel.add(magminSp);

        magmaxSM = new SpinnerNumberModel(magmax, magmin, magmax, 0.1);
        JSpinner magmaxSp = new JSpinner(magmaxSM);
        magPanelCon.gridx = 1;
        magPanelCon.gridy = 1;
        magPanelLayout.setConstraints(magmaxSp, magPanelCon);
        magPanel.add(magmaxSp);

        ccP.gridx = 0;
        ccP.gridy = 0;
        contentPaneLayout.setConstraints(magPanel, ccP);
        add(magPanel);

        JPanel timeResPanel = new JPanel();
        timeResPanel.setPreferredSize(magPanel.getPreferredSize());
        timeResPanel.setBorder(BorderFactory
                .createTitledBorder("Time Resolution"));
        String[] resChoices = { TimeSlider.YEAR, TimeSlider.MONTH,
                TimeSlider.DAY };
        timeResCombo = new JComboBox(resChoices);
        timeResPanel.add(timeResCombo);

        ccP.gridx = 0;
        ccP.gridy = 1;
        contentPaneLayout.setConstraints(timeResPanel, ccP);
        add(timeResPanel);

        JPanel timePanel = new JPanel();
        timePanel.setBorder(BorderFactory.createTitledBorder("Time Limits"));
        GridBagLayout timePanelLayout = new GridBagLayout();
        GridBagConstraints timePanelCon = new GridBagConstraints();
        timePanel.setLayout(timePanelLayout);
        final JLabel yearLabel = new JLabel("Year");
        final JLabel monthLabel = new JLabel("Month");
        final JLabel dayLabel = new JLabel("Day");
        final JLabel timeMinLabel = new JLabel("Min");
        final JLabel timeMaxLabel = new JLabel("Max");

        long timemin = QuakeMaxMinData.getDBMinTime();
        long timemax = QuakeMaxMinData.getDBMaxTime();

        yearminSM = new SpinnerNumberModel(TimeUtil.getYear(timemin), TimeUtil
                .getYear(timemin), TimeUtil.getYear(timemax), 1);

        yearmaxSM = new SpinnerNumberModel(TimeUtil.getYear(timemax), TimeUtil
                .getYear(timemin), TimeUtil.getYear(timemax), 1);

        final JSpinner yearminSp = new JSpinner(yearminSM);
        ((JSpinner.NumberEditor) yearminSp.getEditor()).getFormat()
                .setGroupingSize(4);
        yearminSp.setValue(yearminSp.getNextValue());
        yearminSp.setValue(yearminSp.getPreviousValue());

        final JSpinner yearmaxSp = new JSpinner(yearmaxSM);
        ((JSpinner.NumberEditor) yearmaxSp.getEditor()).getFormat()
                .setGroupingSize(5);
        yearmaxSp.setValue(yearmaxSp.getPreviousValue());
        yearmaxSp.setValue(yearmaxSp.getNextValue());

        monthminSM = new SpinnerNumberModel(1, 1, 12, 1);
        monthmaxSM = new SpinnerNumberModel(12, 1, 12, 1);
        dayminSM = new SpinnerNumberModel(1, 1, 31, 1);
        daymaxSM = new SpinnerNumberModel(31, 1, 31, 1);

        final JSpinner monthminSp = new JSpinner(monthminSM);
        final JSpinner monthmaxSp = new JSpinner(monthmaxSM);
        final JSpinner dayminSp = new JSpinner(dayminSM);
        final JSpinner daymaxSp = new JSpinner(daymaxSM);
        timePanelCon.gridx = 1;
        timePanelCon.gridy = 0;
        timePanelCon.anchor = GridBagConstraints.WEST;
        timePanelLayout.setConstraints(timeMinLabel, timePanelCon);
        timePanel.add(timeMinLabel);
        timePanelCon.gridx = 2;
        timePanelCon.gridy = 0;
        timePanelLayout.setConstraints(timeMaxLabel, timePanelCon);
        timePanel.add(timeMaxLabel);
        timePanelCon.gridx = 0;
        timePanelCon.gridy = 1;
        timePanelCon.fill = GridBagConstraints.NONE;
        timePanelLayout.setConstraints(dayLabel, timePanelCon);
        timePanel.add(dayLabel);
        timePanelCon.gridx = 1;
        timePanelCon.gridy = 1;
        timePanelCon.fill = GridBagConstraints.BOTH;
        timePanelLayout.setConstraints(dayminSp, timePanelCon);
        timePanel.add(dayminSp);
        timePanelCon.gridx = 2;
        timePanelCon.gridy = 1;
        timePanelCon.fill = GridBagConstraints.BOTH;
        timePanelLayout.setConstraints(daymaxSp, timePanelCon);
        timePanel.add(daymaxSp);
        final JSeparator daySep = new JSeparator();
        timePanelCon.gridx = 0;
        timePanelCon.gridy = 2;
        timePanelCon.gridwidth = GridBagConstraints.REMAINDER;
        timePanelCon.insets = new Insets(10, 0, 10, 0);
        timePanelLayout.setConstraints(daySep, timePanelCon);
        timePanel.add(daySep);

        timePanelCon.gridx = 0;
        timePanelCon.gridy = 3;
        timePanelCon.insets = new Insets(0, 0, 0, 0);
        timePanelCon.fill = GridBagConstraints.NONE;
        timePanelCon.gridwidth = 1;
        timePanelLayout.setConstraints(monthLabel, timePanelCon);
        timePanel.add(monthLabel);
        timePanelCon.gridx = 1;
        timePanelCon.gridy = 3;
        timePanelCon.fill = GridBagConstraints.BOTH;
        timePanelLayout.setConstraints(monthminSp, timePanelCon);
        timePanel.add(monthminSp);
        timePanelCon.gridx = 2;
        timePanelCon.gridy = 3;
        timePanelCon.fill = GridBagConstraints.BOTH;
        timePanelLayout.setConstraints(monthmaxSp, timePanelCon);
        timePanel.add(monthmaxSp);
        final JSeparator monthSep = new JSeparator();
        timePanelCon.gridx = 0;
        timePanelCon.gridy = 4;
        timePanelCon.gridwidth = GridBagConstraints.REMAINDER;
        timePanelCon.insets = new Insets(10, 0, 10, 0);
        timePanelLayout.setConstraints(monthSep, timePanelCon);
        timePanel.add(monthSep);

        timePanelCon.gridx = 0;
        timePanelCon.gridy = 5;
        timePanelCon.gridwidth = 1;
        timePanelCon.insets = new Insets(0, 0, 0, 0);
        timePanelLayout.setConstraints(yearLabel, timePanelCon);
        timePanel.add(yearLabel);
        timePanelCon.gridx = 1;
        timePanelCon.gridy = 5;
        timePanelLayout.setConstraints(yearminSp, timePanelCon);
        timePanel.add(yearminSp);
        timePanelCon.gridx = 2;
        timePanelCon.gridy = 5;
        timePanelLayout.setConstraints(yearmaxSp, timePanelCon);
        timePanel.add(yearmaxSp);

        // timeResCombo.addActionListener(buttonsListener);
        timeResCombo.setActionCommand(pack);

        timeResCombo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JComboBox cb = (JComboBox) e.getSource();
                String selStr = (String) cb.getSelectedItem();
                if (selStr.equals(TimeSlider.YEAR)) {
                    dayLabel.setVisible(false);
                    dayminSp.setVisible(false);
                    daymaxSp.setVisible(false);
                    daySep.setVisible(false);
                    monthLabel.setVisible(false);
                    monthminSp.setVisible(false);
                    monthmaxSp.setVisible(false);
                    monthSep.setVisible(false);
                    yearLabel.setVisible(true);
                    yearminSp.setVisible(true);
                    yearmaxSp.setVisible(true);
                } else if (selStr.equals(TimeSlider.MONTH)) {
                    dayLabel.setVisible(false);
                    dayminSp.setVisible(false);
                    daymaxSp.setVisible(false);
                    daySep.setVisible(false);
                    monthLabel.setVisible(true);
                    monthminSp.setVisible(true);
                    monthmaxSp.setVisible(true);
                    monthSep.setVisible(true);
                    yearLabel.setVisible(true);
                    yearminSp.setVisible(true);
                    yearmaxSp.setVisible(false);
                } else if (selStr.equals(TimeSlider.DAY)) {
                    dayLabel.setVisible(true);
                    dayminSp.setVisible(true);
                    daymaxSp.setVisible(true);
                    daySep.setVisible(true);
                    monthLabel.setVisible(true);
                    monthminSp.setVisible(true);
                    monthmaxSp.setVisible(false);
                    monthSep.setVisible(false);
                    yearLabel.setVisible(true);
                    yearminSp.setVisible(true);
                    yearmaxSp.setVisible(false);
                }
                invalidate();
                validate();
            }
        });

        // By default time resolution is year.
        dayLabel.setVisible(false);
        dayminSp.setVisible(false);
        daymaxSp.setVisible(false);
        daySep.setVisible(false);
        monthLabel.setVisible(false);
        monthminSp.setVisible(false);
        monthmaxSp.setVisible(false);
        monthSep.setVisible(false);
        yearLabel.setVisible(true);
        yearminSp.setVisible(true);
        yearmaxSp.setVisible(true);

        ccP.gridx = 0;
        ccP.gridy = 2;
        contentPaneLayout.setConstraints(timePanel, ccP);
        add(timePanel);

        // bottomPanel consists of 2 buttons: OK and Cancel.
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
        JButton b1 = new JButton("OK");
        b1.addActionListener(buttonsListener);
        b1.setActionCommand(OK);
        bottomPanel.add(b1);

        JButton b2 = new JButton("Cancel");
        b2.addActionListener(buttonsListener);
        b2.setActionCommand(CANCEL);
        bottomPanel.add(b2);

        ccP.gridx = 0;
        ccP.gridy = 3;
        contentPaneLayout.setConstraints(bottomPanel, ccP);
        add(bottomPanel);
        updateValues();
    }

    public void updateValues() {

        magMin = magminSM.getNumber().doubleValue();
        magMax = magmaxSM.getNumber().doubleValue();

        yearMin = yearminSM.getNumber().intValue();
        yearMax = yearmaxSM.getNumber().intValue();

        monthMin = monthminSM.getNumber().intValue();
        monthMax = monthmaxSM.getNumber().intValue();

        dayMin = dayminSM.getNumber().intValue();
        dayMax = daymaxSM.getNumber().intValue();
    }

}
